package com.sys.service.impl;

import com.sys.entity.SysUser;
import com.sys.exception.CustomException;
import com.sys.mapper.SysUserMapper;
import com.sys.service.UserService;
import com.sys.utils.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Service
public class UserServiceImpl implements UserService {

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Override
    public SysUser register(SysUser user) {
        SysUser existingUser = sysUserMapper.findByPhone(user.getPhone());
        if (existingUser != null) {
            throw new CustomException("Phone number already exists");
        }
        String encodedPassword = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(encodedPassword);
        user.setRole("user"); // Default role
        sysUserMapper.save(user);
        return user;
    }

    @Override
    public String login(String phone, String password) {
        SysUser user = sysUserMapper.findByPhone(phone);
        if (user == null || !bCryptPasswordEncoder.matches(password, user.getPassword())) {
            throw new CustomException("Invalid phone number or password");
        }
        return jwtTokenUtil.generateToken(user);
    }
    
    @Override
    public boolean sendVerifyCode(String phone, String type) {
        // 验证手机号格式
        if (phone == null || !phone.matches("^1[3-9]\\d{9}$")) {
            throw new CustomException("Invalid phone number format");
        }
        
        // 检查用户是否存在（重置密码时需要）
        if ("reset_password".equals(type)) {
            SysUser user = sysUserMapper.findByPhone(phone);
            if (user == null) {
                throw new CustomException("Phone number not registered");
            }
        }
        
        // TODO: 集成短信服务商API发送验证码
        // 这里暂时只记录日志，实际不发送验证码
        logger.info("Sending verify code to phone: {}, type: {}", phone, type);
        
        // TODO: 生成验证码并存储到Redis/缓存中，设置过期时间
        // String verifyCode = generateVerifyCode();
        // redisTemplate.opsForValue().set("verify_code:" + phone, verifyCode, 5, TimeUnit.MINUTES);
        
        // 暂时返回成功，等待后续集成短信服务
        return true;
    }
    
    @Override
    public boolean resetPassword(String phone, String verifyCode, String newPassword) {
        // 验证手机号格式
        if (phone == null || !phone.matches("^1[3-9]\\d{9}$")) {
            throw new CustomException("Invalid phone number format");
        }
        
        // 验证新密码格式
        if (newPassword == null || newPassword.length() < 6) {
            throw new CustomException("Password must be at least 6 characters long");
        }
        
        // 查询用户是否存在
        SysUser user = sysUserMapper.findByPhone(phone);
        if (user == null) {
            throw new CustomException("Phone number not registered");
        }
        
        // TODO: 验证验证码是否正确
        // 暂时跳过验证码验证，等待后续集成短信服务
        // String cachedCode = redisTemplate.opsForValue().get("verify_code:" + phone);
        // if (cachedCode == null || !cachedCode.equals(verifyCode)) {
        //     throw new CustomException("Invalid or expired verify code");
        // }
        
        logger.info("Resetting password for phone: {}, verify code: {} (not validated)", phone, verifyCode);
        
        // 加密新密码
        String encodedPassword = bCryptPasswordEncoder.encode(newPassword);
        
        // 更新密码
        user.setPassword(encodedPassword);
        int updated = sysUserMapper.updateById(user);
        
        if (updated > 0) {
            logger.info("Password reset successfully for phone: {}", phone);
            // TODO: 删除已使用的验证码
            // redisTemplate.delete("verify_code:" + phone);
            return true;
        }
        
        return false;
    }
}